package com.zhaopin.test;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.commons.io.FileUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.*;

/**
 * feature转json格式
 */
public class FeatureToJson {

    private static Set<String> funcNames = new HashSet<>();

    static {
        funcNames.add("func_concat_data");
        funcNames.add("func_filter_data");
        funcNames.add("func_first_not_null_data");
        funcNames.add("func_mapping_data");
        funcNames.add("func_static_data");
        funcNames.add("func_topN_data");
        funcNames.add("func_uppercase_data");
        funcNames.add("func_lowercase_data");
        funcNames.add("func_distinct_data");
        funcNames.add("func_result_nlp");
        funcNames.add("func_result_normal");

        funcNames.add("func_handle_data");
        funcNames.add("func_split_data");
        funcNames.add("func_replace_data");
        funcNames.add("func_containall");
        funcNames.add("func_analyzer_data");
        funcNames.add("func_string_data");
        funcNames.add("func_flatmap_data");
        funcNames.add("func_hit_count");
        funcNames.add("func_merge_data_tomap");
        funcNames.add("func_pattern_data");
        funcNames.add("func_weight_range_data");
        funcNames.add("func_contains_element");
        funcNames.add("func_contains");
        funcNames.add("func_set_null_judge");
        funcNames.add("getJsonFieldFromJson");


        funcNames.add("feature_jd_third_level_and_similar");

    }

    public static void main(String[] args) throws Exception {

        List<FlowNode> roots = new ArrayList<>();
        Map<String, JSONObject> jsons = new HashMap<>();
        String name = "feature_jd_name_from_code";
        String desc = "";

        File file = new File("E:\\project\\python\\exp\\experiment\\feature_groovy\\feature_groovy\\feature_jd_name_from_code.groovy");
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));

        //state = 1读取注解信息  state == 2 读取内容
        int state = 1;
        String paraName = null;
        JSONObject jsonObject = null;
        boolean begin = false;
        String line;
        while (!(line = br.readLine()).equals("}")) {


            if (line.trim().equals("") || line.trim().startsWith("//") || line.contains("?")) {
                continue;
            }

            if (line.contains("runScript")) {
                state = 2;
                continue;
            }
            if (state == 1 && line.startsWith("@Field")) {
                line = line.replace("+", "");
                line = line.replace("@Field", "").replaceFirst("String", "");
                line = line.replaceAll("\"", "");
                System.out.println(line);
                String[] tmpArr = line.split("=");
                paraName = tmpArr[0].trim();

                if ("noteDesc".equals(paraName)) {
                    desc = tmpArr[1].trim();
                }
            }
            if (state == 2) {
                if (line.contains("getBehaviorFeatureFromQu")) {
                    begin = true;
                    getBehaviorFeatureFromQu(jsons, line, roots);
                    continue;
                }
                if (line.contains("getJsonFieldFromQu")) {
                    begin = true;
                    judgeGetJsonFieldFromQu(jsons, line, roots);
                    continue;
                }
                if (line.contains("getJsonFieldWithFilterFromQu")) {
                    judgeGetJsonFieldWithFilterFromQu(jsons, line, roots);
                    continue;
                }
                line = line.replace("def", "");
                line = line.replace(" ", "");
                if (line.contains("[:]")) {
                    String[] tarr = line.split("=");
                    String paName = tarr[0].trim();
                    jsonObject = new JSONObject();
                    jsonObject.put("type", "function");
                    JSONObject paramJson = new JSONObject();
                    jsonObject.put("param", paramJson);

                    outer:
                    while (true) {
                        line = br.readLine();
                        if (line.trim().equals("") || line.trim().startsWith("//")) {
                            continue;
                        }

                        for (String funcName : funcNames) {
                            if (line.contains(funcName)) {
                                jsonObject.put("name", funcName);
                                break outer;
                            }
                        }

                        String[] sarr = line.split("=");
                        String tmp = sarr[0].trim().substring(sarr[0].trim().indexOf(paName + ".") + (paName + ".").length());
                        if (line.contains("new JSONArray") || line.contains("new  JSONArray")) {
                            line = line.replace("new  JSONArray(", "").replace("new JSONArray(", "").replace(")", "").replace("[", "").replace("]", "");
                            sarr = line.split("=");
                            tmp = sarr[0].trim().substring(sarr[0].trim().indexOf(paName + ".") + (paName + ".").length());
                            if (!"".equals(sarr[1].trim())) {
                                String[] jarv = sarr[1].trim().split(",");
                                JSONArray ja = new JSONArray();
                                for (int i = 0; i < jarv.length; i++) {
                                    if (jarv[i].contains(".")) {
                                        ja.add(Float.parseFloat(jarv[i].trim()));
                                    } else {
                                        ja.add(Integer.parseInt(jarv[i].trim()));
                                    }
                                }
                                paramJson.put(tmp, ja);
                            }
                        } else {
                            if (tmp.equals("defaultValue")) {
                                paramJson.put("defaultValue", "999999");
                            } else if (tmp.equals("source") || tmp.equals("dataSource") || tmp.equals("target") || tmp.equals("regSource") || tmp.equals("thirdLevelCode") || tmp.equals("key") || tmp.equals("value")) {
                                JSONObject pfn = jsons.get(sarr[1].trim());
                                paramJson.put(tmp, pfn);
                            } else {
                                String v = sarr[1].trim();
                                if (v.contains("\"")) {
                                    //字符串
                                    paramJson.put(tmp, sarr[1].trim().replaceAll("\"", ""));
                                } else {
                                    if (v.equals("true") || v.equals("false")) {
                                        paramJson.put(tmp, Boolean.parseBoolean(v));
                                    } else {
                                        //数字
                                        if (v.contains(".")) {
                                            paramJson.put(tmp, Float.parseFloat(v));
                                        } else {
                                            paramJson.put(tmp, Integer.parseInt(v));
                                        }
                                    }
                                }
                            }
                        }


                    }
                    String[] farr = line.split("=");
                    String varName = farr[0].replace("def", "").trim();
                    jsons.put(varName, jsonObject);
                } else {
                    if (line.contains("[") && line.contains("]")) {

                        jsonObject = new JSONObject();
                        jsonObject.put("type", "function");
                        JSONArray paramJson = new JSONArray();
                        jsonObject.put("param", paramJson);

                        line = line.replace("[", "").replace("]", "");
                        String[] tarr = line.split("=");
                        String[] sarr = tarr[1].split(",");
                        for (String s : sarr) {
                            JSONObject pfn = jsons.get(s);
                            paramJson.add(pfn);
                        }

                        outer:
                        while (true) {
                            line = br.readLine();
                            if (line.equals("") || line.trim().startsWith("//")) {
                                continue;
                            }
                            for (String funcName : funcNames) {
                                if (line.contains(funcName)) {
                                    jsonObject.put("name", funcName);
                                    break outer;
                                }
                            }
                        }
                        String[] farr = line.split("=");
                        String varName = farr[0].replace("def", "").trim();
                        jsons.put(varName, jsonObject);
                    } else {
                        String[] tarr = line.split("\\.");
                        String paName = tarr[0].trim();

                        jsonObject = new JSONObject();
                        jsonObject.put("type", "function");
                        JSONObject paramJson = new JSONObject();
                        jsonObject.put("param", paramJson);

                        outer:
                        do {
//                                line = br.readLine();
//                                if (line.equals("") || line.trim().startsWith("//")) {
//                                    continue;
//                                }
                            for (String funcName : funcNames) {
                                if (line.contains(funcName)) {
                                    jsonObject.put("name", funcName);
                                    break outer;
                                }
                            }
                            String[] sarr = line.split("=");
                            String tmp = sarr[0].trim().substring(sarr[0].trim().indexOf(paName + ".") + (paName + ".").length());
                            if (tmp.equals("defaultValue")) {
                                paramJson.put("defaultValue", "999999");
                            } else if (tmp.equals("source") || tmp.equals("dataSource") || tmp.equals("target") || tmp.equals("regSource") || tmp.equals("thirdLevelCode") || tmp.equals("key") || tmp.equals("value")) {
                                JSONObject pfn = jsons.get(sarr[1].trim());
                                paramJson.put(tmp, pfn);
                            } else {
                                String v = sarr[1].trim();
                                if (v.contains("\"")) {
                                    //字符串
                                    paramJson.put(tmp, sarr[1].trim().replaceAll("\"", ""));
                                } else {
                                    if (v.equals("true") || v.equals("false")) {
                                        paramJson.put(tmp, Boolean.parseBoolean(v));
                                    } else {
                                        //数字
                                        if (v.contains(".")) {
                                            paramJson.put(tmp, Float.parseFloat(v));
                                        } else {
                                            paramJson.put(tmp, Integer.parseInt(v));
                                        }
                                    }
                                }
                            }

                            while (true) {
                                line = br.readLine();
                                if (line.equals("") || line.trim().startsWith("//")) {
                                    continue;
                                } else {
                                    break;
                                }
                            }
                        } while (true);
                        String[] farr = line.split("=");
                        String varName = farr[0].replace("def", "").trim();
                        jsons.put(varName, jsonObject);
                    }
                }
            }
        }
        System.out.println(jsonObject.toJSONString());

        JSONObject featureJson = jsonObject;
        featureJson.put("id", name);
//            featureJson.put("name",name);
        featureJson.put("desc", desc);

//        System.out.println(featureJson.toJSONString());
        System.out.println(JSON.toJSONString(featureJson, SerializerFeature.DisableCircularReferenceDetect));


    }

    private static void judgeGetJsonFieldWithFilterFromQu(Map<String, JSONObject> jsons, String line, List<FlowNode> roots) {
        JSONObject jsonObj = new JSONObject();
        jsonObj.put("type", "function");
        jsonObj.put("name", "getJsonFieldWithFilterFromQu");
        JSONArray paramJson = new JSONArray();
        jsonObj.put("param", paramJson);

        String[] arr = line.split("=");
        String varName = arr[0].replaceAll("def", "").trim();

        line = line.substring(line.indexOf("(") + 1, line.length() - 1);
        line = line.replaceAll("\"", "");
        String[] tmpArr = line.split(",");
        paramJson.add(tmpArr[0].trim().replaceAll("\"", ""));
        jsons.put(varName, jsonObj);
    }

    private static void judgeGetJsonFieldFromQu(Map<String, JSONObject> jsons, String line, List<FlowNode> roots) {
        JSONObject jsonObj = new JSONObject();
        jsonObj.put("type", "function");
        jsonObj.put("name", "getJsonFieldFromQu");
        JSONArray paramJson = new JSONArray();
        jsonObj.put("param", paramJson);

        String[] arr = line.split("=");
        String varName = arr[0].replaceAll("def", "").trim();

        line = line.substring(line.indexOf("(") + 1, line.length() - 1);
        line = line.replaceAll("\"", "");
        String[] tmpArr = line.split(",");
        paramJson.add(tmpArr[0].trim().replaceAll("\"", ""));
//        paramJson.put("key", tmpArr[0].trim().replaceAll("\"", ""));

        if (tmpArr.length == 2) {
            paramJson.add(Boolean.parseBoolean(tmpArr[1].trim()));
//            paramJson.put("toInt", Boolean.parseBoolean(tmpArr[1].trim()));
        }
        jsons.put(varName, jsonObj);
    }

    private static void getBehaviorFeatureFromQu(Map<String, JSONObject> jsons, String line, List<FlowNode> roots) {
        JSONObject jsonObj = new JSONObject();
        jsonObj.put("type", "function");
        jsonObj.put("name", "getBehaviorFeatureFromQu");
        JSONArray paramJson = new JSONArray();
        jsonObj.put("param", paramJson);

        String[] arr = line.split("=");
        String varName = arr[0].replaceAll("def", "").trim();

        line = line.substring(line.indexOf("(") + 1, line.length() - 1);
        line = line.replaceAll("\"", "");
        String[] tmpArr = line.split(",");

        paramJson.add(tmpArr[0].trim().replaceAll("\"", ""));
//        paramJson.put("featureName", tmpArr[0].trim().replaceAll("\"", ""));
        if (tmpArr.length == 2) {
            paramJson.add(Integer.parseInt(tmpArr[1].trim()));
//            paramJson.put("type", Integer.parseInt(tmpArr[1].trim()));
        }


        if (tmpArr.length == 3) {
            paramJson.add(Integer.parseInt(tmpArr[1].trim()));
            paramJson.add(Boolean.parseBoolean(tmpArr[2]));
//            paramJson.put("distinct", Boolean.parseBoolean(tmpArr[2]));
        }
        if (tmpArr.length == 4) {
            paramJson.add(Integer.parseInt(tmpArr[1].trim()));
            paramJson.add(Boolean.parseBoolean(tmpArr[2]));
            paramJson.add(Boolean.parseBoolean(tmpArr[3]));
//            paramJson.put("removeContain", Boolean.parseBoolean(tmpArr[3]));
        }
        jsons.put(varName, jsonObj);
    }


    private static void toMarkDown(StringBuffer sb, List<FlowNode> roots) {
        for (int i = 0; i < roots.size(); i++) {
            FlowNode fn = roots.get(i);
            if (fn.isSteped()) {
                continue;
            }
            String fnName = fn.getFuncName();
            fn.setSteped(true);
            for (FlowNode child : fn.getChildren()) {
                String cnFuncName = child.getFuncName();
                sb.append(fnName + "aaa" + fn.getId()).append("-->").append(cnFuncName + "aaa" + child.getId()).append("\n");
            }
            toMarkDown(sb, fn.getChildren());
        }


    }
}
